"""
Python3.3新加了yield from语法

核心知识：
    1.yield from的用法：yield from iterable
"""

from itertools import chain


def my_chain(*args, **kwargs):
    for my_iterable in args:
        for value in my_iterable:
            yield value


def yield_from_chain(*args, **kwargs):
    for my_iterable in args:
        # yield from的用法：yield from iterable
        yield from my_iterable


def use_chain():
    user_list = ["Kevin", "葛小伦"]
    company_dict = {
        "GOOG": "Google",
        "APPL": "Apple"
    }

    for value in chain(user_list, company_dict, [1, 2, 3]):
        print(value)
    # 输出结果：
    """
    Kevin
    葛小伦
    GOOG
    APPL
    1
    2
    3
    """

    for value in my_chain(user_list, company_dict, [1, 2, 3]):
        print(value)
    # 输出结果：
    """
    Kevin
    葛小伦
    GOOG
    APPL
    1
    2
    3
    """

    for value in yield_from_chain(user_list, company_dict, [1, 2, 3]):
        print(value)
    # 输出结果：
    """
    Kevin
    葛小伦
    GOOG
    APPL
    1
    2
    3
    """


def g1(gen):
    yield from gen


def main():
    # main（调用方） g1（委托生成器） gen（子生成器）
    # 1. yield from 会在调用方与子生成器建立一个双向通道

    g = g1()
    g.send(None)


final_result = {}


def middle(key):
    """
    委托生成器
    """

    while True:
        # 子生成器sales_sum(key), 使用yield from可以避免处理StopIteration
        final_result[key] = yield from sales_sum(key)
        print(key + "销量统计完成")


def use_middle():
    """
    调用方
    """

    data_sets = {
        "面膜": [1200, 1500, 3000],
        "手机": [28, 55, 98, 108],
        "大衣": [280, 560, 778, 70],
    }
    for key, data_set in data_sets.items():
        print("start key:", key)
        m = middle(key)
        # 预激middle协程
        m.send(None)
        for value in data_set:
            # 给协程传递每一组的值
            m.send(value)
        m.send(None)
    print("final_result:", final_result)
    # 输出结果：
    """
    start key: 大衣
    大衣销量:  280
    大衣销量:  560
    大衣销量:  778
    大衣销量:  70
    大衣销量:  None
    大衣销量统计完成
    start key: 面膜
    面膜销量:  1200
    面膜销量:  1500
    面膜销量:  3000
    面膜销量:  None
    面膜销量统计完成
    start key: 手机
    手机销量:  28
    手机销量:  55
    手机销量:  98
    手机销量:  108
    手机销量:  None
    手机销量统计完成
    final_result: {'大衣': (1688, [280, 560, 778, 70]), '面膜': (5700, [1200, 1500, 3000]), '手机': (289, [28, 55, 98, 108])}
    """


def sales_sum(pro_name):
    total = 0
    nums = []
    while True:
        x = yield
        print(pro_name + "销量: ", x)
        if not x:
            break
        total += x
        nums.append(x)
    return total, nums


def use_sales_sum():
    my_gen = sales_sum("手机")
    my_gen.send(None)
    my_gen.send(1200)
    my_gen.send(1500)
    my_gen.send(3000)

    try:
        my_gen.send(None)
    except StopIteration as e:
        result = e.value
        print(result)
    # 输出结果：
    """
    手机销量:  1200
    手机销量:  1500
    手机销量:  3000
    手机销量:  None
    (5700, [1200, 1500, 3000])
    """


if __name__ == '__main__':
    # use_chain()
    # use_middle()
    use_sales_sum()
